package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 动态的点赞，喜欢，评论
     *
     * @param comment
     * @return
     */
    @Override
    public int save(Comment comment) {
        //1. 添加记录到评论表
        //1.1 补充动态的作者targetUserId
        //1.2 通过动态id查询动态表  5个并发 10  => 15
        Publish publish = mongoTemplate.findById(comment.getTargetId(), Publish.class);
        //1.3 设置targetUserId
        comment.setTargetUserId(publish.getUserId());
        //1.4 设置创建时间
        comment.setCreated(System.currentTimeMillis());
        //1.5 添加
        mongoTemplate.insert(comment);

        //2. 更新动态表中的点赞数+1
        //2.1 构建条件, 动态的id
        Query query = new Query(Criteria.where("_id").is(comment.getTargetId()));
        //2.2 构建更新对象
        Update update = new Update();
        // 防止并发时，缺少了赞的数, 使用自增长
        update.inc(comment.getCol(), 1);
        // 更新
        mongoTemplate.updateFirst(query,update, Publish.class);
        //3. 查询最新的动态点赞数再返回, 保证是最新的值，防止并发时数量不一致
        publish = mongoTemplate.findById(comment.getTargetId(), Publish.class);
        switch (comment.getCommentType()){
            case 1: return publish.getLikeCount(); // 点赞数
            case 2: return publish.getCommentCount(); // 评论数
            case 3: return publish.getLoveCount(); // 喜欢数
            default: return 0;
        }
    }

    /**
     * 动态的取消点赞
     *
     * @param pojo
     * @return
     */
    @Override
    public int remove(Comment pojo) {
        //1. 删除评论表数据
        //1.1 构建删除的条件
        Query query = new Query(Criteria.where("userId").is(pojo.getUserId())
                .and("targetId").is(pojo.getTargetId())
                .and("commentType").is(pojo.getCommentType()));
        //1.2 删除
        mongoTemplate.remove(query, Comment.class);

        //2.1 构建条件, 动态的id
        Query publishQuery = new Query(Criteria.where("_id").is(pojo.getTargetId()));
        //2.2 构建更新对象
        Update update = new Update();
        // 防止并发时，缺少了赞的数, 使用自减长
        update.inc(pojo.getCol(), -1);
        // 更新
        mongoTemplate.updateFirst(publishQuery,update, Publish.class);
        //3. 查询最新的动态点赞数再返回, 保证是最新的值，防止并发时数量不一致
        Publish publish = mongoTemplate.findById(pojo.getTargetId(), Publish.class);
        switch (pojo.getCommentType()){
            case 1: return publish.getLikeCount(); // 点赞数
            case 2: return publish.getCommentCount(); // 评论数
            case 3: return publish.getLoveCount(); // 喜欢数
            default: return 0;
        }
    }

    /**
     * 分页查询某条动态的评论
     *
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult findPage(String publishId, Long page, Long pageSize) {
        //1. 构建查询的条件
        Query query = new Query(Criteria.where("targetId").is(new ObjectId(publishId))
                .and("commentType").is(2));// 2代表评论
        //2. 总数
        long total = mongoTemplate.count(query, Comment.class);
        //3. 总数>0
        List<Comment> commentList = new ArrayList<>();
        if(total > 0) {
            //4. 设置分页参数
            query.skip((page-1)*pageSize).limit(pageSize.intValue());
            //5. 时间降序
            query.with(Sort.by(Sort.Order.desc("created")));
            //6. 查询
            commentList = mongoTemplate.find(query, Comment.class);
        }
        //7. 构建PageResult返回
        return PageResult.pageResult(page,pageSize,commentList,total);
    }

    /**
     * 对评论的点赞
     *
     * @param comment
     * @return
     */
    @Override
    public int saveComment(Comment comment) {
        //1. 添加记录到评论表
        //1.1 补充评论的作者targetUserId(键盘侠路过)
        //1.2 通过评论的id(键盘侠路过)查询评论表  5个并发 10  => 15
        Comment commentInDb = mongoTemplate.findById(comment.getTargetId(), Comment.class);
        //1.3 设置targetUserId  (键盘侠路过的作者id)
        comment.setTargetUserId(commentInDb.getUserId());
        //1.4 设置创建时间
        comment.setCreated(System.currentTimeMillis());
        //1.5 添加
        mongoTemplate.insert(comment);

        //2. 更新评论表中(键盘侠路过)的点赞数+1
        //2.1 构建条件, 评论的id
        Query query = new Query(Criteria.where("_id").is(comment.getTargetId()));
        //2.2 构建更新对象
        Update update = new Update();
        // 防止并发时，缺少了赞的数, 使用自增长.评论表的点赞数
        update.inc("likeCount", 1);
        // 更新
        mongoTemplate.updateFirst(query,update, Comment.class);
        //3. 查询最新的评论点赞数再返回, 保证是最新的值，防止并发时数量不一致
        commentInDb = mongoTemplate.findById(comment.getTargetId(), Comment.class);
        return commentInDb.getLikeCount();
    }

    /**
     * 对评论的取消点赞
     *
     * @param pojo
     * @return
     */
    @Override
    public int removeComment(Comment pojo) {
        //1. 删除评论表数据
        //1.1 构建删除的条件
        Query query = new Query(Criteria.where("userId").is(pojo.getUserId())
                .and("targetId").is(pojo.getTargetId())
                .and("commentType").is(pojo.getCommentType()));
        //1.2 删除
        mongoTemplate.remove(query, Comment.class);

        //2.1 构建条件, 评论的id
        Query commentQuery = new Query(Criteria.where("_id").is(pojo.getTargetId()));
        //2.2 构建更新对象
        Update update = new Update();
        // 防止并发时，缺少了赞的数, 使用自减长
        update.inc("likeCount", -1);
        // 更新
        mongoTemplate.updateFirst(commentQuery,update, Comment.class);
        //3. 查询最新的评论点赞数再返回, 保证是最新的值，防止并发时数量不一致
        return mongoTemplate.findById(pojo.getTargetId(), Comment.class).getLikeCount();
    }

    /**
     * 谁点赞、喜欢、评论了我 列表
     *
     * @param loginUserId
     * @param commentType //评论类型，1-点赞，2-评论，3-喜欢
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult findPageByCommentType(Long loginUserId, int commentType, Long page, Long pageSize) {
        //1. 构建查询的条件
        Query query = new Query(Criteria.where("targetUserId").is(loginUserId)
                .and("commentType").is(commentType));
        //2. 总数
        long total = mongoTemplate.count(query, Comment.class);
        //3. 总数>0
        List<Comment> commentList = new ArrayList<>();
        if (total>0) {
            //4. 设置分页参数
            query.skip((page-1)*pageSize).limit(pageSize.intValue());
            //5. 按时间降序
            query.with(Sort.by(Sort.Order.desc("created")));
            //6. 分页查询
            commentList = mongoTemplate.find(query, Comment.class);
        }
        //7. 构建pageResult返回
        return PageResult.pageResult(page,pageSize,commentList,total);
    }
}
